
#include "Block.h"
#include "Duplicate/IDuplicate.h"
#include "Common/TableData/BlockBlockCfg.h"
#include "BlockMgr.h"

Block::Block()
{
	m_blockId = 0;
	m_byState = 0;
	m_changeCount = 0;
	m_pBlockCfg = nullptr;
	m_dupId = 0;
	m_sceneId = 0;
}

Block::~Block()
{

}

//初始化
bool Block::intit(uint32_t blockId,uint32_t dupId,uint32_t sceneId)
{
	m_pBlockCfg = g_GetBlockBlockCfgTable()->GetBlockBlockCfgInfo(blockId);
	if (nullptr == m_pBlockCfg)
	{
		LogErrFmtPrint("[logic] Block::intit...nullptr == m_pBlockCfg...blockId:%u ", blockId);
		return false;
	}
	m_blockId = blockId;
	m_byState = m_pBlockCfg->initState;
	m_changeCount = 0;
	m_dupId = dupId;
	m_sceneId = sceneId;
	LogDebugFmtPrint("[logic] Block::intit.... dupid:%u, sceneid:%u, blockid:%u , state:%d ", m_dupId,m_sceneId,  m_blockId, m_byState);

	return true;
}
//
void Block::uninit()
{
	m_blockId = 0;
	m_byState = 0;
	m_changeCount = 0;
	m_pBlockCfg = nullptr;
}

//改变阻挡状态
bool Block::changeState()
{
	if (nullptr != m_pBlockCfg)
	{
		if (EBlock_Change_Infinite == m_pBlockCfg->useTimes
			|| m_changeCount < m_pBlockCfg->useTimes
			)
		{
			++m_changeCount;
			if (EBlock_InitState_Close == m_byState)
			{
				m_byState = EBlock_InitState_Open;
			}
			else
			{
				m_byState = EBlock_InitState_Close;
			}
			return true;
		}
	}
	return false;
}














DupBlock::DupBlock()
{
	m_pBlockCfg = nullptr;
	m_mapBlock.clear();
	m_pDuplicate = nullptr;
}
DupBlock::~DupBlock()
{

}

bool DupBlock::Init(IDuplicate *pDuplicate)
{
	if (nullptr == pDuplicate)
	{
		return false;
	}
	m_pBlockCfg = pDuplicate->GetBlockCfg();
	if (nullptr == m_pBlockCfg)
	{
		return false;
	}
	uint32_t dupId = pDuplicate->GetDuplicateID();
	uint32_t sceneId = pDuplicate->GetSceneID();
	//统计需要创建的阻挡
	SET_UINT32 setNewBlock;
	setNewBlock.clear();
	//进入区域
	MAP_UINT32_SET_UINT32::iterator iter = m_pBlockCfg->mapSetEnterArea.begin();
	for (; iter != m_pBlockCfg->mapSetEnterArea.end(); ++iter)
	{
		SET_UINT32 &setBlock = iter->second;
		SET_UINT32::iterator iterBlock = setBlock.begin();
		for (; iterBlock != setBlock.end(); ++iterBlock)
		{
			setNewBlock.insert(*iterBlock);
		}
	}

	//死亡
	VecDieBlockCfg::iterator iterDie = m_pBlockCfg->vecDieBlock.begin();
	for (; iterDie != m_pBlockCfg->vecDieBlock.end(); ++iterDie)
	{
		DieBlockCfgInfo &info = (*iterDie);
		SET_UINT32 &setBlock = info.setBlock;
		SET_UINT32::iterator iterBlock = setBlock.begin();
		for (; iterBlock != setBlock.end(); ++iterBlock)
		{
			setNewBlock.insert(*iterBlock);
		}
	}

	//出生
	VecBornBlockCfg::iterator iterBorn = m_pBlockCfg->vecBornBlock.begin();
	for (; iterBorn != m_pBlockCfg->vecBornBlock.end(); ++iterBorn)
	{
		BornBlckCfgInfo &info = (*iterBorn);
		SET_UINT32 &setBlock = info.setBlock;
		SET_UINT32::iterator iterBlock = setBlock.begin();
		for (; iterBlock != setBlock.end(); ++iterBlock)
		{
			setNewBlock.insert(*iterBlock);
		}
	}

	//使用物件
	MAP_UINT32_SET_UINT32::iterator iterUse = m_pBlockCfg->mapUseThing.begin();
	for (; iterUse != m_pBlockCfg->mapUseThing.end(); ++iterUse)
	{
		SET_UINT32 &setBlock = iterUse->second;
		SET_UINT32::iterator iterBlock = setBlock.begin();
		for (; iterBlock != setBlock.end(); ++iterBlock)
		{
			setNewBlock.insert(*iterBlock);
		}
	}

	SET_UINT32::iterator iterNew = setNewBlock.begin();
	for (; iterNew != setNewBlock.end(); ++iterNew)
	{
		uint32_t blockId = (*iterNew);
		IBlock *pBlock = g_GetBlockMgr()->MakeBlockObj();
		if (nullptr == pBlock)
		{
			UnInit();
			return false;
		}
		if (!pBlock->intit(blockId,dupId,sceneId))
		{
			UnInit();
			return false;
		}
		m_mapBlock[blockId] = pBlock;
	}
	m_pDuplicate = pDuplicate;

	return true;
}

void DupBlock::UnInit()
{
	BlockMap::iterator iter = m_mapBlock.begin();
	for (; iter != m_mapBlock.end(); ++iter)
	{
		IBlock *pBlock = iter->second;
		g_GetBlockMgr()->RecycleBlock(pBlock);
	}
	m_pBlockCfg = nullptr;
	m_mapBlock.clear();
	m_pDuplicate = nullptr;
}


IBlock *DupBlock::GetBlock(uint32_t blockId)
{
	BlockMap::iterator iter = m_mapBlock.find(blockId);
	return (iter != m_mapBlock.end()) ? iter->second : nullptr;
}

void DupBlock::NotifyBlockState(MAP_UINT32_INT8 &mapBlockState)
{
	if (nullptr != m_pDuplicate && mapBlockState.size() > 0)
	{
		//通知副本内玩家，阻挡状态变化
		Duplicate_NotifyBlockStateRsp rsp;
		DupAllBlockStateProto *proto = rsp.mutable_dup_block();
		if (nullptr != proto)
		{
			MAP_UINT32_INT8::iterator iterState = mapBlockState.begin();
			for (; iterState != mapBlockState.end(); ++iterState)
			{
				DupBlockStateProto *protoBlock = proto->add_all_block();
				if (nullptr != protoBlock)
				{
					protoBlock->set_block_id(iterState->first);
					protoBlock->set_state(iterState->second);
				}
				LogDebugFmtPrint("[logic] DupBlock::NotifyBlockState....dupid:%u, sceneid:%u ,  blockid:%u , state:%d ",m_pDuplicate->GetDuplicateID(),m_pDuplicate->GetSceneID(),iterState->first,iterState->second);
			}
		}
		m_pDuplicate->BroadCastData(EMODULE_ID_DUPLICATE, LOGIC_TO_CLIENT_DUPLICATE_BLOCK_STATE, &rsp);
	}
}

//获取阻挡状态
void DupBlock::GetAllBlockState(MAP_UINT32_INT8 &mapBlockState)
{
	BlockMap::iterator iter = m_mapBlock.begin();
	for (; iter != m_mapBlock.end(); ++iter)
	{
		IBlock *pBlock = iter->second;
		if (nullptr != pBlock)
		{
			mapBlockState[iter->first] = pBlock->blockState();
		}
	}
}


//玩家进入区域
void DupBlock::OnEnterArea(uint32_t areaId)
{
	if (nullptr == m_pBlockCfg)
	{
		return;
	}
	MAP_UINT32_INT8 mapBlockState;
	mapBlockState.clear();
	MAP_UINT32_SET_UINT32::iterator iter = m_pBlockCfg->mapSetEnterArea.find(areaId);
	if (iter != m_pBlockCfg->mapSetEnterArea.end())
	{
		SET_UINT32 &setBlock = iter->second;
		SET_UINT32::iterator iterBlock = setBlock.begin();
		for (; iterBlock != setBlock.end(); ++iterBlock)
		{
			uint32_t blockId = (*iterBlock);
			IBlock *pBlock = GetBlock(blockId);
			if (nullptr != pBlock && pBlock->changeState())
			{
				mapBlockState[blockId] = pBlock->blockState();
			}
		}
	}
	NotifyBlockState(mapBlockState);
}
//怪物死亡
void DupBlock::OnMonsDie(uint32_t monsId, int32_t count, uint32_t formationId)
{
	if (nullptr == m_pBlockCfg)
	{
		return;
	}
	MAP_UINT32_INT8 mapBlockState;
	mapBlockState.clear();
	VecDieBlockCfg::iterator iter = m_pBlockCfg->vecDieBlock.begin();
	for (; iter != m_pBlockCfg->vecDieBlock.end(); ++iter)
	{
		DieBlockCfgInfo &info = (*iter);
		SET_UINT32::iterator iterFomartion = info.setDie.find(formationId);
		if (iterFomartion == info.setDie.end())
		{
			continue;
		}
		if (info.mapDieMonster.size() <= 0)
		{
			continue;
		}
		MAP_UINT32_UINT32::iterator iterMon = info.mapDieMonster.find(monsId);
		if (iterMon == info.mapDieMonster.end())
		{
			continue;
		}
		if (iterMon->second >= (uint32_t)count)
		{
			iterMon->second -= count;
		}
		else
		{
			iterMon->second = 0;
		}
		//
		if (iterMon->second <= 0)
		{
			info.mapDieMonster.erase(iterMon);
		}

		if (0 == info.mapDieMonster.size())
		{
			//编队怪物全部都死亡了
			SET_UINT32::iterator iterBlock = info.setBlock.begin();
			for (; iterBlock != info.setBlock.end(); ++iterBlock)
			{
				uint32_t blockId = (*iterBlock);
				IBlock *pBlock = GetBlock(blockId);
				if (nullptr != pBlock && pBlock->changeState())
				{
					mapBlockState[blockId] = pBlock->blockState();
				}
			}
		}

	}
	NotifyBlockState(mapBlockState);
}
//使用物件
void DupBlock::OnUseThing(uint32_t thingId)
{
	if (nullptr == m_pBlockCfg)
	{
		return;
	}
	MAP_UINT32_SET_UINT32::iterator iter = m_pBlockCfg->mapUseThing.find(thingId);
	if (iter == m_pBlockCfg->mapUseThing.end())
	{
		return;
	}
	MAP_UINT32_INT8 mapBlockState;
	mapBlockState.clear();
	SET_UINT32 &setBlock = iter->second;
	SET_UINT32::iterator iterBlock = setBlock.begin();
	for (; iterBlock != setBlock.end(); ++iterBlock)
	{
		uint32_t blockId = (*iterBlock);
		IBlock *pBlock = GetBlock(blockId);
		if (nullptr != pBlock && pBlock->changeState())
		{
			mapBlockState[blockId] = pBlock->blockState();
		}
	}
	NotifyBlockState(mapBlockState);
}

//怪物出生
void DupBlock::OnMonsBorn(uint32_t monsId, uint32_t formationId)
{
	//LogErrFmtPrint("[logic] DupBlock::OnMonsBorn...monsid:%u , formationid:%u ", monsId,formationId);
	if (nullptr == m_pBlockCfg)
	{
		return;
	}
	MAP_UINT32_INT8 mapBlockState;
	mapBlockState.clear();
	VecBornBlockCfg::iterator iter = m_pBlockCfg->vecBornBlock.begin();
	for (; iter != m_pBlockCfg->vecBornBlock.end(); ++iter)
	{
		BornBlckCfgInfo &info = (*iter);
		SET_UINT32::iterator iterFomartion = info.setBorn.find(formationId);
		if (iterFomartion == info.setBorn.end())
		{
			continue;
		}
		if (info.mapBornMonster.size() <= 0)
		{
			continue;
		}
		MAP_UINT32_UINT32::iterator iterMon = info.mapBornMonster.find(monsId);
		if (iterMon == info.mapBornMonster.end())
		{
			continue;
		}
		if (iterMon->second > 0)
		{
			iterMon->second -= 1;
		}
		else
		{
			iterMon->second = 0;
		}
		//
		if (iterMon->second <= 0)
		{
			info.mapBornMonster.erase(iterMon);
		}

		if (0 == info.mapBornMonster.size())
		{
			//编队怪物全部都出生了
			SET_UINT32::iterator iterBlock = info.setBlock.begin();
			for (; iterBlock != info.setBlock.end(); ++iterBlock)
			{
				uint32_t blockId = (*iterBlock);
				IBlock *pBlock = GetBlock(blockId);
				if (nullptr != pBlock && pBlock->changeState())
				{
					mapBlockState[blockId] = pBlock->blockState();
				}
			}
		}

	}
	NotifyBlockState(mapBlockState);
}